package com.xiaochong.bitong.api.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xc.logclient.utils.LogTrace;
import com.xiaochong.bitong.api.constant.HttpHeaderCons;
import com.xiaochong.bitong.api.constant.ReturnCode;
import com.xiaochong.bitong.api.constant.SmsCodeType;
import com.xiaochong.bitong.api.service.CommonService;
import com.xiaochong.bitong.api.service.UserService;
import com.xiaochong.bitong.api.userclient.JsonView;
import com.xiaochong.bitong.api.utils.ApiVersion;
import com.xiaochong.bitong.api.utils.CaptchaKeyUtils;
import com.xiaochong.bitong.api.utils.RequestUtil;
import com.xiaochong.service.common.config.redis.RedisServer;
import com.xiaochong.tir.common.data.po.About;
import com.xiaochong.tir.common.data.po.CCountryNum;
import com.xiaochong.tir.common.data.vo.ApiResultVo;
import com.xiaochong.tir.common.data.vo.BtUser;
import com.xiaochong.tir.common.data.vo.CountrysData;
import com.xiaochong.tir.common.data.vo.app.UserVo;
import com.xiaochong.tir.common.util.DateUtils;
import com.xiaochong.tir.common.util.RedisKeyApp;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 通证指数
 * @author daizhiqing
 */
@RestController
@Api(value = "用户操作相关")
@RequestMapping(value = ApiVersion.API_V1_PREFIX+"/user")
public class UserController {

	@Autowired
	UserService userService;
	@Autowired
	RedisServer redisServer;
	@Autowired
	CommonService commonService;

	/**
	 * 获取国别手机号码
	 * @return
	 */
	@ApiOperation(value = "获取国别号" , notes = "获取国别号")
	@GetMapping("/getCountryNum")
	public ApiResultVo<List<CCountryNum>> getCountryNum(){
		ApiResultVo apiResultVo=  new ApiResultVo();
		try {
			List<CountrysData> cCountryNumList = userService.getCountryNums();
			apiResultVo.setData(cCountryNumList);
			apiResultVo.setCode(ReturnCode.SUCCESS);
		}catch (Exception e){
			apiResultVo.setCode(ReturnCode.ERROR);
            apiResultVo.setMessage(e.getMessage());
			LogTrace.error(e.getMessage() ,e);
			e.printStackTrace();
		}
		return apiResultVo;
	}


	@ApiOperation(value = "发送登录验证码" , notes = "发送登录验证码:000000(成功)000009(需要开启图形验证码)500000(系统异常)100101(验证码错误)100102(手机验证码请求频繁30s),100106(验证码发送失败)")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "countryNum", value = "国别号", required = true, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "account", value = "账号", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "captchaCode", value = "易盾验证", required = false, dataType = "String", paramType = "query")
	})
	@PostMapping("/sendLoginSmsCode")
	public ApiResultVo<String> sendLoginSmsCode(@RequestParam(value = "countryNum", required = true)String countryNum,
										@RequestParam(value = "account", required = true)String account,
                                                @RequestParam(value = "captchaCode",required = false) String captchaCode){

		ApiResultVo apiResultVo=  new ApiResultVo();
		apiResultVo.setTradeId(LogTrace.getTrace().getTraceId());
		int reqCount=0,reqMax=3;
		try {

			String smsCountKey = RedisKeyApp.CODE_COUNT+DateUtils.getCurrentDateString()+":"+account;

			// 校验手机号码今天是第几次 发送登录短信
			if(redisServer.exists(smsCountKey)){
				String val=redisServer.get(smsCountKey);
				reqCount=Integer.valueOf(val);
			}

			reqCount++;
			// 这个时候就需要校验验证码了
			boolean showBol1 = reqCount > reqMax ;
			boolean showBol2 = StringUtils.isEmpty(captchaCode);
			if(showBol1 && showBol2){
				apiResultVo.setCode(ReturnCode.AUTH_CODE_EMPTY);
				apiResultVo.setMessage("图形验证不通过");
				return apiResultVo;
			}

			// 验证用户的图形验证码
			if (showBol1 && !CaptchaKeyUtils.sendCode(captchaCode)) {
				LogTrace.infoKvs("网易易盾验证", "account" , account,"captchaCode", captchaCode);

				apiResultVo.setCode(ReturnCode.VALID_CODE_ERR);
				apiResultVo.setMessage("图形验证不通过");

				return apiResultVo;
			}

			JsonView jsonView = userService.sendSmsCode(countryNum , account ,SmsCodeType.LOGIN ,null);

			if(jsonView != null && ReturnCode.SUCCESS.equals(jsonView.getCode())){
				String codeToken = JSONObject.parseObject(jsonView.getData().toString()).getString("result");
				if(StringUtils.isNotBlank(codeToken)){
					redisServer.set(RedisKeyApp.Code_TOKEN+account , codeToken , RedisKeyApp.ExpireTime.FIVE_MINI);
					redisServer.set(smsCountKey ,reqCount , RedisKeyApp.ExpireTime.ONE_DAY );
					apiResultVo.setCode(ReturnCode.SUCCESS);
				}
			}else{
				apiResultVo.setCode(jsonView.getCode());
				apiResultVo.setMessage(jsonView.getMsg());
			}
		}catch (Exception e){
			apiResultVo.setCode(ReturnCode.ERROR);
            apiResultVo.setMessage(e.getMessage());
			LogTrace.error(e.getMessage() ,e);
			e.printStackTrace();
		}
		return  apiResultVo;
	}


	@ApiOperation(value = "注销登录" , notes = "注销登录")
	@PostMapping("/logout"+HttpHeaderCons.AUTH_URL)
	public ApiResultVo logout(HttpServletRequest request){
		ApiResultVo apiResultVo=  new ApiResultVo();
		apiResultVo.setTradeId(LogTrace.getTrace().getTraceId());
		try {
			String token = RequestUtil.getHeaderName(request  , HttpHeaderCons.TOKEN);
			userService.logoutUserToken(token);
			apiResultVo.setCode(ReturnCode.SUCCESS);
		}catch (Exception e){
			apiResultVo.setCode(ReturnCode.ERROR);
            apiResultVo.setMessage(e.getMessage());
			LogTrace.error(e.getMessage() ,e);
			e.printStackTrace();
		}
		return  apiResultVo;
	}

	@ApiOperation(value = "手机验证码登录" , notes = "000000(成功，会返回token),000006(参数错误),100101(手机验证码错误),000004(用户不存在),100107(账户存在，但状态不可用),500000(系统异常情况)")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "countryNum", value = "国别号", required = true, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "account", value = "手机号码", required = true, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String", paramType = "query")
	})
	@PostMapping("/loginByCode")
	public ApiResultVo<String> loginByCode(@RequestParam(value = "countryNum", required = true)String countryNum,
								   @RequestParam(value = "account", required = true)String account,
								   @RequestParam(value = "code", required = true)String code
								   ){
		ApiResultVo apiResultVo=  new ApiResultVo();
		apiResultVo.setTradeId(LogTrace.getTrace().getTraceId());
		try {

			String codeTokenKey = RedisKeyApp.Code_TOKEN+account;

			String codeToken = redisServer.get(codeTokenKey);
			if(StringUtils.isBlank(codeToken)){
				apiResultVo.setCode(ReturnCode.PARAMS_ERROR);
				apiResultVo.setMessage("手机验证码错误");
			}else {
				JsonView jsonView = userService.smsCodeLogin(countryNum , account , code , codeToken);
				if(ReturnCode.SUCCESS.equals(jsonView.getCode())){
					//登录成功
					UserVo userVo =  JSONObject.parseObject(jsonView.getData().toString()  ,UserVo.class);
					String token  = userVo.getToken();
					LogTrace.infoKvs("用户登录成功","account",account , "token" ,token);
					apiResultVo.setData(token);
					apiResultVo.setMessage("用户登录成功");
					apiResultVo.setCode(ReturnCode.SUCCESS);

				}else{
					apiResultVo.setCode(jsonView.getCode());
					apiResultVo.setMessage(jsonView.getMsg());
				}
			}

		}catch (Exception e){
			apiResultVo.setCode(ReturnCode.ERROR);
            apiResultVo.setMessage(e.getMessage());
			LogTrace.error(e.getMessage() ,e);
			e.printStackTrace();
		}
		return  apiResultVo;
	}


	@ApiOperation(value = "更新用户名" , notes = "000000(成功)，100108(用户名已存在),500000(系统异常情况)")
	@PostMapping("/updateUserNickname"+HttpHeaderCons.AUTH_URL)
	public ApiResultVo updateUserNickname(HttpServletRequest request ,
										  @RequestParam(value = "nickName", required = true)String nickName){
		ApiResultVo apiResultVo=  new ApiResultVo();
		apiResultVo.setTradeId(LogTrace.getTrace().getTraceId());
		try {
			String token = RequestUtil.getHeaderName(request  , HttpHeaderCons.TOKEN);
			if(userService.setUserName(token , nickName)){
				apiResultVo.setCode(ReturnCode.SUCCESS);
			}else {
				apiResultVo.setCode(ReturnCode.DATA_EXIST);
				apiResultVo.setMessage("该用户名已存在");
			}
		}catch (Exception e){
			apiResultVo.setCode(ReturnCode.ERROR);
            apiResultVo.setMessage(e.getMessage());
			LogTrace.error(e.getMessage() ,e);
			e.printStackTrace();
		}
		return  apiResultVo;
	}


	@ApiOperation(value = "更新用户头像" , notes = "000000(成功，返回头像复制)，000006(用户操作无效),500000(系统异常情况)")
	@PostMapping("/updateHeadImg"+HttpHeaderCons.AUTH_URL)
	public ApiResultVo<String> updateHeadImg(HttpServletRequest request ,
									 @RequestParam(value = "headImg", required = true) MultipartFile headImg){
		ApiResultVo apiResultVo=  new ApiResultVo();
		apiResultVo.setTradeId(LogTrace.getTrace().getTraceId());
		try {
			String token = RequestUtil.getHeaderName(request  , HttpHeaderCons.TOKEN);

			BtUser btUser = commonService.getUserByToken(token);

			if(btUser == null){
				apiResultVo.setCode(ReturnCode.PARAMS_ERROR);
				apiResultVo.setMessage("用户操作无效");
			}else{
				String imageUrl = commonService.uploadFile(headImg , btUser.getId());
				if(StringUtils.isNotBlank(imageUrl)){
					apiResultVo.setCode(ReturnCode.SUCCESS);
					apiResultVo.setData(imageUrl);
					btUser.setImageUrl(imageUrl);
					commonService.refreshUserToken(token , btUser);
				}else {
					apiResultVo.setCode(ReturnCode.DATA_NOT_EXIST);
					apiResultVo.setMessage("上传图片路径为空");
				}
			}
		}catch (Exception e){
			apiResultVo.setCode(ReturnCode.ERROR);
            apiResultVo.setMessage(e.getMessage());
			LogTrace.error(e.getMessage() ,e);
			e.printStackTrace();
		}
		return  apiResultVo;
	}

    @ApiOperation(value = "加载用户信息" , notes = "000000(成功，返回用户信息)，000004(无用户信息),500000(系统异常情况)")
    @PostMapping("/loadUserInfo"+HttpHeaderCons.AUTH_URL)
	public ApiResultVo<BtUser> loadUserInfo(HttpServletRequest request){
        ApiResultVo apiResultVo=  new ApiResultVo();
        apiResultVo.setTradeId(LogTrace.getTrace().getTraceId());
        try {
            String token = RequestUtil.getHeaderName(request  , HttpHeaderCons.TOKEN);

            BtUser btUser = commonService.getUserByToken(token);
            if(btUser != null){
                btUser.setId(0);
                apiResultVo.setData(btUser);
                apiResultVo.setCode(ReturnCode.SUCCESS);
            }else {
                apiResultVo.setCode(ReturnCode.DATA_NOT_EXIST);
                apiResultVo.setMessage("无用户信息");
            }

        }catch (Exception e){
            apiResultVo.setCode(ReturnCode.ERROR);
            apiResultVo.setMessage(e.getMessage());
            LogTrace.error(e.getMessage() ,e);
            e.printStackTrace();
        }

        return apiResultVo;
    }

	@ApiOperation(value = "币通官方社群 / 关于币通" , notes = "000000(成功，返回用户信息)，000004(暂无数据),500000(系统异常情况)")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "type", value = "类型 官方社群1 / 关于币通2", required = true, dataType = "String", paramType = "query")
	})
	@PostMapping("/getAppAboutList")
    public ApiResultVo getAppAboutList(@RequestParam(value = "type", required = true)String type){
		ApiResultVo apiResultVo=  new ApiResultVo();
		apiResultVo.setTradeId(LogTrace.getTrace().getTraceId());
		try {
			List<About> aboutList = userService.getAppAboutList(type);

			if(aboutList == null || aboutList.size()<=0){
				apiResultVo.setCode(ReturnCode.DATA_NOT_EXIST);
				apiResultVo.setMessage("暂无数据");
			}else{
				apiResultVo.setCode(ReturnCode.SUCCESS);
				apiResultVo.setData(aboutList);
			}
		}catch (Exception e){
			apiResultVo.setCode(ReturnCode.ERROR);
			apiResultVo.setMessage(e.getMessage());
			LogTrace.error(e.getMessage() ,e);
			e.printStackTrace();
		}
		return apiResultVo;
	}
}
